a972f869be7eaeca8e214844d0492fd1d5e3bb82,src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java,StaticTypeCheckingSupport,chooseBestMethod,#ClassNode#Collection#ClassNode#,692

Before Change


            if (params.length > args.length && ! isVargs(params)) {
                // GROOVY-5231
                int dist = allParametersAndArgumentsMatchWithDefaultParams(params, args);
                if (dist>=0 && !receiver.equals(m.getDeclaringClass())) dist+=getDistance(receiver, m.getDeclaringClass());
                if (dist>=0 && dist<bestDist) {
                    bestChoices.clear();
                    bestChoices.add(m);
                    bestDist = dist;
                } else if (dist>=0 && dist==bestDist) {
                    bestChoices.add(m);
                }
            } else if (params.length == args.length) {
                int allPMatch = allParametersAndArgumentsMatch(params, args);
                int lastArgMatch = isVargs(params)?lastArgMatchesVarg(params, args):-1;
                if (lastArgMatch>=0) lastArgMatch++; // ensure exact matches are preferred over vargs
                int dist = allPMatch>=0?Math.max(allPMatch, lastArgMatch):lastArgMatch;
                if (dist>=0 && !receiver.equals(m.getDeclaringClass())) dist+=getDistance(receiver, m.getDeclaringClass());
                if (dist>=0 && dist<bestDist) {
                    bestChoices.clear();
                    bestChoices.add(m);
                    bestDist = dist;
                } else if (dist>=0 && dist==bestDist) {
                    bestChoices.add(m);
                }
            } else if (isVargs(params)) {
                boolean firstParamMatches = true;
                // check first parameters
                if (args.length > 0) {
                    Parameter[] firstParams = new Parameter[params.length - 1];
                    System.arraycopy(params, 0, firstParams, 0, firstParams.length);
                    firstParamMatches = allParametersAndArgumentsMatch(firstParams, args) >= 0;
                }
                if (firstParamMatches) {
                    // there are three case for vargs
                    // (1) varg part is left out
                    if (params.length == args.length + 1) {
                        if (bestDist > 1) {
                            bestChoices.clear();
                            bestChoices.add(m);
                            bestDist = 1;
                        }
                    } else {
                        // (2) last argument is put in the vargs array
                        //      that case is handled above already
                        // (3) there is more than one argument for the vargs array
                        int dist = excessArgumentsMatchesVargsParameter(params, args);
                        if (dist >= 0 && !receiver.equals(m.getDeclaringClass())) dist++;
                        // varargs methods must not be preferred to methods without varargs
                        // for example :
                        // int sum(int x) should be preferred to int sum(int x, int... y)

After Change


     * @return the list of methods which best matches the argument types. It is still possible that multiple
     * methods match the argument types.
     */
    public static List<MethodNode> chooseBestMethod(final ClassNode receiver, Collection<MethodNode> methods, ClassNode... args) {
        if (methods.isEmpty()) return Collections.emptyList();
        List<MethodNode> bestChoices = new LinkedList<MethodNode>();
        int bestDist = Integer.MAX_VALUE;
        ClassNode actualReceiver;
        for (MethodNode m : methods) {
            actualReceiver = receiver!=null?receiver:m.getDeclaringClass();
            // todo : corner case
            /*
                class B extends A {}

                Animal foo(A o) {...}
                Person foo(B i){...}

                B  a = new B()
                Person p = foo(b)
             */

            Parameter[] params = parameterizeArguments(actualReceiver, m);
            if (params.length > args.length && ! isVargs(params)) {
                // GROOVY-5231
                int dist = allParametersAndArgumentsMatchWithDefaultParams(params, args);
                if (dist>=0 && !actualReceiver.equals(m.getDeclaringClass())) dist+=getDistance(actualReceiver, m.getDeclaringClass());
                if (dist>=0 && dist<bestDist) {
                    bestChoices.clear();
                    bestChoices.add(m);
                    bestDist = dist;
                } else if (dist>=0 && dist==bestDist) {
                    bestChoices.add(m);
                }
            } else if (params.length == args.length) {
                int allPMatch = allParametersAndArgumentsMatch(params, args);
                int lastArgMatch = isVargs(params)?lastArgMatchesVarg(params, args):-1;
                if (lastArgMatch>=0) lastArgMatch++; // ensure exact matches are preferred over vargs
                int dist = allPMatch>=0?Math.max(allPMatch, lastArgMatch):lastArgMatch;
                if (dist>=0 && !actualReceiver.equals(m.getDeclaringClass())) dist+=getDistance(actualReceiver, m.getDeclaringClass());
                if (dist>=0 && dist<bestDist) {
                    bestChoices.clear();
                    bestChoices.add(m);
                    bestDist = dist;
                } else if (dist>=0 && dist==bestDist) {
                    bestChoices.add(m);
                }
            } else if (isVargs(params)) {
                boolean firstParamMatches = true;
                // check first parameters
                if (args.length > 0) {
                    Parameter[] firstParams = new Parameter[params.length - 1];
                    System.arraycopy(params, 0, firstParams, 0, firstParams.length);
                    firstParamMatches = allParametersAndArgumentsMatch(firstParams, args) >= 0;
                }
                if (firstParamMatches) {
                    // there are three case for vargs
                    // (1) varg part is left out
                    if (params.length == args.length + 1) {
                        if (bestDist > 1) {
                            bestChoices.clear();
                            bestChoices.add(m);
                            bestDist = 1;
                        }
                    } else {
                        // (2) last argument is put in the vargs array
                        //      that case is handled above already
                        // (3) there is more than one argument for the vargs array
                        int dist = excessArgumentsMatchesVargsParameter(params, args);
                        if (dist >= 0 && !actualReceiver.equals(m.getDeclaringClass())) dist++;
                        // varargs methods must not be preferred to methods without varargs
                        // for example :
                        // int sum(int x) should be preferred to int sum(int x, int... y)